﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.Protocols;
using System.DirectoryServices.ActiveDirectory;
using System.DirectoryServices.AccountManagement;

namespace CompareDominoAD
{
    class MainProgram
    {
        /// <summary>
        /// Checks if the account exists in the Active Directory
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="givenName"></param>
        /// <param name="sn"></param>
        /// <returns></returns>
        static bool UserExist(string uid, string givenName, string sn)
        {
            int resultCount = 0;
            try
            {
                PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
                using (PrincipalSearcher ps = new PrincipalSearcher())
                {
                    UserPrincipal user = new UserPrincipal(ctx);
                    user.SamAccountName = uid;
                    ps.QueryFilter = user;
                    PrincipalSearchResult<Principal> results = ps.FindAll();
                    resultCount = results.Count<Principal>();
                    results.Dispose();
                    user.Dispose();

                    if (resultCount == 0)
                    {
                        user = new UserPrincipal(ctx);
                        if (givenName.Length != 0)
                        {
                            user.GivenName = givenName;
                        }
                        user.Surname = sn;
                        ps.QueryFilter = user;
                        results = ps.FindAll();
                        resultCount = results.Count<Principal>();
                    }
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
            }
            return (resultCount == 0) ? false : true;
        }
        /// <summary>
        /// Creates the user in the Active Directory.
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="givenName"></param>
        /// <param name="sn"></param>
        /// <param name="emailAddress"></param>
        static void CreateUser(string uid, string givenName, string sn, string middleInitial, string emailAddress)
        {
            string name = sn + ", " + givenName;

            try
            {
                PrincipalContext ctx = new PrincipalContext(
                    ContextType.Domain, 
                    null, 
                    "OU=Migrated,OU=User,DC=c,DC=s,DC=m");

                UserPrincipal user = new UserPrincipal(ctx);
                
                user.SetPassword("password");

                if (middleInitial.Length > 0)
                {
                    name = sn + ", " + givenName + " " + middleInitial;
                    user.MiddleName = middleInitial;
                }
                
                if (givenName.Length > 0)
                {
                    user.GivenName = givenName;
                    user.DisplayName = name;
                    user.Name = name;
                }
                else
                {
                    user.DisplayName = sn;
                    user.Name = sn;
                }

                user.Surname = sn;
                user.EmailAddress = emailAddress;
                user.Enabled = true;
                user.ExpirePasswordNow();
                user.SamAccountName = uid;
                user.UserPrincipalName = uid + "@c.s.m";
                user.Save();

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
            }
        }
        static void Main(string[] args)
        {

            DirectoryEntry deDomino = new DirectoryEntry("LDAP://dir1/OU=C,O=A", "username", "password", AuthenticationTypes.None);

            System.IO.StreamWriter sw = new System.IO.StreamWriter("testing.txt");
            System.IO.StreamWriter csv = new System.IO.StreamWriter("users_adding_to_ad.csv");

            try
            {
                string uid, mail, givenName, sn, middleInitial;
                foreach (DirectoryEntry dePerson in deDomino.Children)
                {
                    
                    uid = "";
                    mail = "";
                    givenName = "";
                    sn = "";
                    middleInitial = "";
                    
                        try
                        {
                            uid = dePerson.Properties["uid"].Value.ToString();
                            Console.Error.WriteLine("** UID: {0}", uid);

                            mail = dePerson.Properties["mail"].Value.ToString();

                            if (dePerson.Properties["givenName"].Value != null)
                            {
                                givenName = dePerson.Properties["givenName"].Value.ToString();
                            }
                            if (dePerson.Properties["MiddleInitial"].Value != null)
                            {
                                middleInitial = dePerson.Properties["MiddleInitial"].Value.ToString();
                            }
                            sn = dePerson.Properties["sn"].Value.ToString();

                            Console.WriteLine("Searching for {0} {1} - {2}...", givenName, sn, uid);
                            sw.WriteLine("Searching for {0} {1} - {2}...", givenName, sn, uid);

                            if (!UserExist(uid,givenName,sn) )
                            {
                                Console.WriteLine("++ Creating account, {0} {1}...", givenName, sn);
                                sw.WriteLine("++ Creating account, {0} {1}...", givenName, sn);
                                CreateUser(uid, givenName, sn, middleInitial, mail);

                                csv.WriteLine("{0},{1},{2}",
                                    givenName,
                                    sn,
                                    mail);
                                csv.Flush();
                            }
                            else
                            {
                                Console.WriteLine("-- Account Exists in AD for {0} {1}", givenName, sn);
                                sw.WriteLine("-- Account Exists in AD for {0} {1}", givenName, sn);
                            }

                            sw.WriteLine("dsquery user -name {0}*", givenName);
                            sw.WriteLine("dsquery user -name {0}*", sn);
                            sw.WriteLine("dsquery user -samid {0}*", uid);
                            sw.Flush();
                        }
                        catch (Exception e)
                        {
                            Console.Error.WriteLine(e);
                        }
                    
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
            }
            finally
            {
                deDomino.Dispose();
                csv.Close();
                sw.Close();
            }

        }
    }
}
